package com.study.patterns.proxy.dynamic.asm.base;

import jdk.internal.org.objectweb.asm.Type;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;

import java.lang.reflect.InvocationTargetException;

/**
 * Created by tan on 2017/6/21.
 */
public class GenerateClass {
	public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {

		ClassWriter writer = new ClassWriter(0);
		writer.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC,
				"com/study/patterns/proxy/dynamic/asm/base/MyClass", null,
				"java/lang/Object", null);
		//字段的访问
		//字段名
		//字段的disc
		//字段的泛型
		//字段的默认值(仅对static字段有效)
		writer.visitField(Opcodes.ACC_PRIVATE, "name", Type.getDescriptor(String.class), null, null);
		ClassWriterAdapter adapter = new ClassWriterAdapter(writer);

		adapter.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null).visitCode();;//够着函数

		String setMethodDesc = "(" + Type.getDescriptor(String.class) + ")V";
		adapter.visitMethod(Opcodes.ACC_PUBLIC, "setName", setMethodDesc, null, null).visitCode();

		String getMethodDesc = "()" + Type.getDescriptor(String.class);
		adapter.visitMethod(Opcodes.ACC_PUBLIC, "getName", getMethodDesc, null, null).visitCode();
		//System.out.println(new String(writer.toByteArray()));
		//writer.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC+Opcodes.ACC_ABSTRACT+Opcodes.ACC_INTERFACE, );
		MyClassLoader classLoader = new MyClassLoader();
		Class<?> clazz = classLoader.defineClass("com.study.patterns.proxy.dynamic.asm.base.MyClass", writer.toByteArray());

		Object object = clazz.newInstance();
		System.out.println(clazz.getMethod("getName").invoke(object));

		clazz.getMethod("setName", String.class).invoke(object, "tanhai");
		System.out.println(clazz.getMethod("getName").invoke(object));
	}


	static class MyClassLoader extends ClassLoader {
		public Class defineClass(String name, byte[] classFile) {
			return defineClass(name, classFile, 0, classFile.length);
		}
	}
}
